package jp.co.brilliantservice.app.openar.view;


import java.util.List;

import jp.jasminesoft.gcat.scalc.LatLong2XY;
import jp.jasminesoft.gcat.scalc.MeshCodeManager;
import jp.jasminesoft.gcat.scalc.XY2LatLong;
import android.content.Context;
import android.graphics.Canvas;
import android.location.Location;
import android.util.AttributeSet;
import android.util.Log;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.Overlay;

public class ArMapView extends MapView {
	static final String API_KEY_DEFAULT = "replace your api key";
	private MyLocation mMyLocation = null;
	private OnLocationChangedListener mOnLocationChangedListener = null;
	private int mRange = 0;
	private boolean mIsMylocationOn = false;
	private List<Overlay> overlayList;

	public ArMapView(Context context) {
		super(context, API_KEY_DEFAULT);
		init(context);
	}

	public ArMapView(Context context, String apiKey) {
		super(context, apiKey);
		init(context);
	}

	public ArMapView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context);
	}

	public ArMapView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init(context);
	}

	private void init(Context context) {
		mMyLocation = new MyLocation(context,this);
		overlayList = getOverlays();
	}

	public void addOverlay(Overlay overlay) {
		overlayList.add(overlay);
	}

	public void removeOverlay(Overlay overlay) {
		overlayList.remove(overlay);
	}

	public void enableMyLocation() {
		this.getOverlays().add(mMyLocation);
		mMyLocation.enableMyLocation();
		mIsMylocationOn = true;
	}

	public void disableMyLocation() {
		this.getOverlays().remove(mMyLocation);
		mMyLocation.disableMyLocation();
		mIsMylocationOn = false;
	}

	public boolean isMyLocationOn() {
		return mIsMylocationOn;
	}

	public synchronized void setOnLocationChangedListener(OnLocationChangedListener l) {
		mOnLocationChangedListener = l;
	}

	public interface OnLocationChangedListener {
		void onLocationChangedListener(Location location);
	}

	class MyLocation extends MyLocationOverlay {
		public MyLocation(Context context, MapView mapView) {
			super(context, mapView);
		}

		@Override
		public synchronized void onLocationChanged(Location location) {
			super.onLocationChanged(location);
			if (mOnLocationChangedListener != null) {
				mOnLocationChangedListener.onLocationChangedListener(location);
			}
		}
		@Override
		protected void drawMyLocation(Canvas arg0, MapView arg1, Location arg2,
				GeoPoint arg3, long arg4) {
			try {
				super.drawMyLocation(arg0, arg1, arg2, arg3, arg4);
			} catch (Exception e) {
				Log.e("Exception", e.getLocalizedMessage());
			}
		}
	};

	public void setRange(int range) {
		mRange = range;
	}

	public void setLocation(double lat, double lon){
		int mLat,mLon;
		LatLong2XY ll2xy = new LatLong2XY(-1);
		MapController mc = this.getController();
		GeoPoint point = new GeoPoint((int)Math.round(lat * 1E6), (int)Math.round(lon * 1E6));
		mc.setCenter(point);

		ll2xy.setLatitude(double2dms(lat));
		ll2xy.setLongitude(double2dms(lon));

		int kei = MeshCodeManager.getInstance().getProperKei(lat, lon);
		XY2LatLong xy2ll1 = new XY2LatLong(kei);
		XY2LatLong xy2ll2 = new XY2LatLong(kei);
		double x = ll2xy.getX();
		double y = ll2xy.getY();
		xy2ll1.setX(x-mRange*1.2);
		xy2ll1.setY(y-mRange*1.2);
		xy2ll2.setX(x+mRange*1.2);
		xy2ll2.setY(y+mRange*1.2);
		mLat = (int)Math.round(((xy2ll2.getLatitude() - xy2ll1.getLatitude()) * 1E6));
		mLon = (int)Math.round(((xy2ll2.getLongitude() - xy2ll1.getLongitude()) * 1E6));
		mc.zoomToSpan(mLat,mLon);
		mc.setCenter(point);
	}

	public Double double2dms(Double d){
		int deg,min,sec;
		deg = (int)Math.floor(d);
		min = (int)Math.floor((d - deg) * 60);
		sec = (int)Math.floor(((d - deg) * 60 - min) *60);
		return (Double.valueOf(String.valueOf(deg) + "." + String.valueOf(min) + String.valueOf(sec)));
	}
}
